<template>
  <div class="folder">
    <el-row style="margin-bottom: 10px">
      <el-progress :text-inside="true" :stroke-width="18" :percentage="bar" style="display: inline-block;width: 90%"/>
      <span class="space">{{convertToFileSize(enterpriseInfo.grossSpace - enterpriseInfo.surplusSpace)}}/{{convertToFileSize(enterpriseInfo.grossSpace)}}</span>
    </el-row>

    <el-row style="margin-bottom: 20px">
      <div>
        <el-button @click="upLoadVisible = true" size="small" round type="primary" icon="ele-Upload">上传</el-button>
        <el-button @click="batchMoveFile" size="small" round icon="ele-Rank" type="info">批量移动文件</el-button>
        <el-button @click="newFolder" size="small" round icon="ele-FolderAdd">新建文件夹</el-button>
        <el-input v-model="searchFileName" placeholder="搜索我的文件" size="small" clearable @clear="getCurrentList"
                  @keydown.enter.native="searchFile" style="width: 160px;margin-left: 10px">
          <template #suffix>
            <el-icon :size="15" color="var(--el-color-primary)">
              <ele-Search/>
            </el-icon>
          </template>
        </el-input>
      </div>
    </el-row>

    <el-row style="margin-bottom: 10px">
      <div class="header">
        <span v-if="queue.length > 1" @click="back" class="back">返回上一级 | </span>
        <span class="path" v-for="(item,index) in queue" @click="skip(index)"
              :class="{'active':index !==0 && index === queue.length-1 ,'pointer': queue.length > 1 && index !== queue.length-1}">
          <el-icon class="icon" v-if="index!==0">
            <component is="ele-ArrowRightBold" />
          </el-icon>
          <span class="path-name">{{ item.name }}</span>
        </span>
      </div>
    </el-row>

    <div v-loading="loading" element-loading-text="加载中...">
      <draggable
          :list="dragList"
          class="list-group"
          animation="300"
          itemKey="id"
          :force-fallback="true"
          @start="drag = true"
          @end="datadragEnd"
          @update="handleUpdateDrag">
        <template #item="{ element , index }">
          <div class="item" @mouseenter="handleMouseenter(index)" @mouseleave="handleMouseleave(index)"  v-if="element.fileName" :class="{select:isShowMenu[index]}">
            <div class="constant">
<!--              <el-icon class="icon">-->
<!--                <component :is="getFileTypeByIcon(element.fileName)" />-->
<!--              </el-icon>-->
              <svg class="icon" aria-hidden="true">
                <use :xlink:href="getFileTypeByIcon(element.fileName)"></use>
              </svg>
            </div>
            <div class="foot">
              <div class="fileName">
                <text>{{element.fileName}}</text>
              </div>
              <div class="check" v-if="isShowMenu[index]">
                <el-checkbox v-model="checkList[index]" @change="changCheckBox(index)" />
              </div>
              <div class="menu" @mouseenter="ifClose = false" v-if="isShowMenu[index]">
                <el-dropdown placement="bottom" :hide-on-click="true" >
                  <span class="el-dropdown-link">
                    <el-icon>
                      <component is="ele-More" />
                    </el-icon>
                  </span>
                  <template #dropdown @mouseleave="ifClose = true">
                    <el-dropdown-menu>
                      <el-dropdown-item icon="ele-View" @click="preview(element)">预览</el-dropdown-item>
                      <el-dropdown-item icon="ele-Download" @click="printDoc(element)">下载</el-dropdown-item>
                      <el-dropdown-item icon="ele-Edit" @click="updateFile(element)">重命名</el-dropdown-item>
                      <el-dropdown-item icon="ele-Delete" @click="removeFileById(element)">删除</el-dropdown-item>
                      <el-dropdown-item icon="ele-Share">共享</el-dropdown-item>
                    </el-dropdown-menu>
                  </template>
                </el-dropdown>
              </div>
            </div>
          </div>

          <div class="item" @mouseenter="handleMouseenterByFolder(element,index)" @mouseleave="handleMouseleave(index)" v-else>
            <el-tooltip
                :show-after="500"
                effect="dark"
                :content="hoverFolderPath"
                placement="top">
              <div class="constant-folder" @click="getNextList(element)">
<!--                <el-icon class="icon">-->
<!--                  <component :is="getFileTypeByIcon(element.name)" />-->
<!--                </el-icon>-->
                <svg class="icon" aria-hidden="true">
                  <use :xlink:href="getFileTypeByIcon(element.fileName)"></use>
                </svg>
              </div>
            </el-tooltip>
            <div class="foot">
              <div class="fileName">
                <span>{{element.name}}</span>
              </div>
              <div class="menu" v-if="isShowMenu[index]" @mouseenter="ifClose = false">
                <el-dropdown placement="bottom" :hide-on-click="true">
                  <span class="el-dropdown-link">
                    <el-icon>
                      <component is="ele-More" />
                    </el-icon>
                  </span>
                  <template #dropdown @mouseleave="ifClose = true">
                    <el-dropdown-menu>
                      <el-dropdown-item icon="ele-FolderChecked" @click="getNextList(element)">进入</el-dropdown-item>
                      <el-dropdown-item icon="ele-Rank" @click="openMove(element)">移动</el-dropdown-item>
                      <el-dropdown-item icon="ele-Edit" @click="updateFolder(element)">重命名</el-dropdown-item>
                      <el-dropdown-item icon="ele-Delete" @click="removeFolderById(element)">删除</el-dropdown-item>
                    </el-dropdown-menu>
                  </template>
                </el-dropdown>
              </div>
            </div>
          </div>
        </template>
      </draggable>
    </div>

    <!-- 上传文件 -->
    <el-dialog v-model="upLoadVisible" title="上传文件" destroy-on-close width="560px">
      <div class="mb-2">
        <el-upload class="upload-demo" drag :auto-upload="false" name="file" :limit="1"
                   :headers="headers" @change="changeFile" :on-exceed="handleExceed" ref="uploadBanner">
          <el-icon class="el-icon--upload">
            <ele-UploadFilled/>
          </el-icon>
          <div class="el-upload__text">
            拖拽上传或 <em>点击上传</em>
          </div>
        </el-upload>
      </div>
      <template #footer>
          <span class="dialog-footer">
            <el-button size="small" @click="upLoadVisible = false">关闭</el-button>
            <el-button size="small" type="primary" icon="ele-UploadFilled" @click="upLoadSubmit()">上传</el-button>
          </span>
      </template>
    </el-dialog>

    <folder-move v-model:dialog-drawer="moveVisible" :selectFolder="currentSelectFolder" :currentSelectFileIds="currentSelectFileIds" @onSubmit="getCurrentList"/>

    <online-preview v-model:dialog-drawer="onlinePreviewisible" :file-data="currentSelectFile" />

  </div>
</template>

<script>
import {ElMessage, ElMessageBox, genFileId} from 'element-plus'
import {onMounted, reactive, toRefs, ref} from "vue";
import draggable from 'vuedraggable'
import { Session } from '/@/utils/storage'

import {
  getFolder,
  getEnterpriseInfo,
  createFolder,
  hoverFolder,
  updateFolderName,
  removeFolder,
  upload, removeFile, download
} from "../../../api/space/manage";
import {getFileTypeByIcon, convertToFileSize, checkVal} from "../../../utils/common";
import FolderMove from "../components/FolderMove.vue";
import OnlinePreview from "../components/OnlinePreview.vue";

export default {
  name: "FolderManage",
  components: {
    draggable,
    FolderMove,
    OnlinePreview
  },
  // props: {
  //   userId: { // 用户id
  //     type: String,
  //     default: null
  //   }
  // },
  setup(props, context) {
    const previewImageRef = ref()
    const uploadBanner = ref()
    const state = reactive({
      loading:true,
      headers:{'17work': Session.get('token')},
      fileList:[],
      file:null,
      upLoadVisible:false,
      onlinePreviewisible:false,
      moveVisible:false,
      lastIndex:null,
      ifClose:true,
      hoverFolderPath:'',
      drag:false,
      bar:0,//进度条
      searchFileName:'',
      enterpriseInfo:'',
      dragList:[],
      isShowMenu:[],
      checkList:[],
      currentSelectFolder:null,
      currentSelectFileIds:[],
      currentSelectFile:null,
      currentFolder:{  //当前的文件夹数据
        name:'全部文件',  //文件夹名称
        parentLevel:'0',  //父级id
        tierLevel:0,  //层级
        id:'0'
      },
      map:new Map(),
      queue:[], //文件夹队列
      folderBatchMoveVo:{
        // 移动的文件
        fileIds:[],
        // 移动的文件夹id
        folderIds:[],
        // 要移动的目录
        parentLevel:'',
        // 原目录
        oldLevel:''
      }
    })
    //拖拽更新
    const handleUpdateDrag = (val) => {

    }
    //获取数据
    const getList = (id) => {
      state.loading = true
      getFolder(id).then(res =>{
        state.dragList = []
        if (res.data.folders){
          state.dragList = state.dragList.concat(res.data.folders)
        }
        state.dragList = state.dragList.concat(res.data.files)
        state.loading = false
      }).catch((e)=>{
        console.log(e)
        state.loading = false
      })
      state.isShowMenu = new Array(state.dragList.length).fill(false)
      state.checkList = new Array(state.dragList.length).fill(false)
    }
    //获取下一层级数据
    const getNextList = (element) => {
      state.loading = true
      getFolder(element.id).then(res =>{
        state.dragList = []
        if (res.data.folders){
          state.dragList = state.dragList.concat(res.data.folders)
        }
        state.dragList = state.dragList.concat(res.data.files)
        state.loading = false
      }).catch((e)=>{
        console.log(e)
        state.loading = false
      })
      state.isShowMenu = new Array(state.dragList.length).fill(false)
      state.checkList = new Array(state.dragList.length).fill(false)
      state.currentFolder.tierLevel += 1
      state.currentFolder.name = element.name
      state.currentFolder.parentLevel = element.parentLevel
      state.currentFolder.id = element.id
      state.queue.push({
        name:element.name,  //文件夹名称
        parentLevel:element.parentLevel,  //父级id
        tierLevel:state.currentFolder.tierLevel + 1,  //层级
        id:element.id
      })
    }
    //重新加载当前文件数据
    const getCurrentList = () => {
      getList(state.queue.length <= 1 ? "0" : state.queue[state.queue.length-1].id) //重新加载当前界面
    }
    //打开新建文件夹
    const newFolder = () => {
      ElMessageBox.prompt('请输入新的文件夹名称', '创建文件夹', {
        confirmButtonText: '提交',
        cancelButtonText: '取消',
      }).then(({ value }) => {
        if(checkFolderName(value.trim())){
          return false
        }
        createFolder({name:value,parentLevel:state.currentFolder.id,tierLevel:state.currentFolder.tierLevel}).then(res =>{
          if(res.data){
            getCurrentList()
          }
        })
      }).catch(() => {
        //点击了取消
      })
    }
    //拖拽结束
    const datadragEnd = () => {
      state.drag = false
    }
    //搜索文件
    const searchFile = () => {
      state.dragList = state.dragList.filter(function(currentValue,index,arr){
        if(arr[index].fileName){
          if(arr[index].fileName.indexOf(state.searchFileName) > -1){
            return arr[index]
          }
        }else{//文件夹
          if(arr[index].name.indexOf(state.searchFileName) > -1){
            return arr[index]
          }
        }
      })
    }
    //鼠标移入
    const handleMouseenter = (index) => {
      //两个hover重叠了 不这么写画面会疯狂抖动
      if (state.lastIndex !== null){
        //判断上一个是否选中
        if(!state.checkList[state.lastIndex]){
          state.isShowMenu[state.lastIndex] = false
        }
        //state.isShowMenu[state.lastIndex] = false
        state.isShowMenu[index] = true
        state.lastIndex = index
      }else{
        state.isShowMenu[index] = true
        state.lastIndex = index
      }
    }
    //鼠标移入-文件夹
    const handleMouseenterByFolder = (element,index) => {
      //两个hover重叠了 不这么写画面会疯狂抖动
      if (state.lastIndex !== null){
        if(!state.checkList[state.lastIndex]){
          state.isShowMenu[state.lastIndex] = false
        }
        // state.isShowMenu[state.lastIndex] = false
        state.isShowMenu[index] = true
        state.lastIndex = index
      }else{
        state.isShowMenu[index] = true
        state.lastIndex = index
      }
      getHoverFolder(element)
    }
    //鼠标移出
    const handleMouseleave = (index) => {
      setTimeout(() => {
        if (state.ifClose){ //判断是否可以隐藏
          if(!state.checkList[index]){
            state.isShowMenu[index] = false
          }
        }
      }, 300);
    }
    //文件夹名称校验
    const checkFolderName = (folderName) => {
      if(folderName == null){
        ElMessage.error("文件夹名称不能为空")
        return true
      }else if (folderName.length === 0 || folderName.length > 30){
        ElMessage.error("文件夹名称长度必须小于30个字符且不能为空")
        return true
      }else if(!checkVal(folderName)){
        ElMessage.error("文件夹名称不能包含特殊字符")
        return true
      }else{
        return false
      }
    }
    //返回上一级
    const back = () => {
      state.queue.pop()
      if (state.queue.length <= 1){
        getList("0")
        initCurrentFolder()
      }else{
        var element = state.queue[state.queue.length-1]
        getList(element.id)
        state.currentFolder.tierLevel -= 1
        state.currentFolder.name = element.name
        state.currentFolder.parentLevel = element.parentLevel
        state.currentFolder.id = element.id
      }
    }
    //更新文件夹名称
    const updateFolder = (element) => {
      ElMessageBox.prompt('请输入新的文件夹名称', '重命名文件夹', {
        confirmButtonText: '提交',
        cancelButtonText: '取消',
        inputPlaceholder:element.name
      }).then(({ value }) => {
        if(checkFolderName(value.trim())){
          return false
        }
        updateFolderName(element.id,value).then(res =>{
          if(res.data){
            ElMessage({
              type: 'success',
              message: '修改成功',
            })
            getCurrentList()
          }
        })
      }).catch(() => {
        //点击了取消
      })
    }
    //重命名文件 TODO 没有这个接口
    const updateFile = (element) => {
      ElMessageBox.prompt('请输入新的文件名称', '重命名文件', {
        confirmButtonText: '提交',
        cancelButtonText: '取消',
        inputPlaceholder:element.fileName
      }).then(({ value }) => {
        if(checkFolderName(value.trim())){ //用的是文件夹的规则
          return false
        }
        ElMessage({
          type: 'info',
          message: '没有该接口',
        })
        // updateFolderName(element.id,value).then(res =>{
        //   if(res.data){
        //     ElMessage({
        //       type: 'success',
        //       message: '修改成功',
        //     })
        //   }
        // })
      }).catch(() => {
        //点击了取消
      })
    }
    //删除文件夹
    const removeFolderById = (element) => {
      ElMessageBox.confirm('确定删除文件夹: ' + element.name + ' ？', {
        confirmButtonText: '删除',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        removeFolder(element.id).then(res => {
          if (!res.data) { //我也不知道为什么返回false
            ElMessage.success('删除成功！')
            getCurrentList()
          }
        }).catch(e => console.log(e))
      }).catch(err => {
      })
    }
    //删除文件
    const removeFileById = (element) => {
      ElMessageBox.confirm('确定删除文件: ' + element.fileName + ' ？', {
        confirmButtonText: '删除',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        removeFile(element.id).then(res => {
          if (res.data) { //我也不知道为什么返回false
            ElMessage.success('删除成功！')
            getCurrentList()
          }
        }).catch(e => console.log(e))
      }).catch(err => {
      })
    }
    //改变上传文件
    const changeFile = (file) => {
      state.file = file.raw
    }
    //提交上传的文件
    const upLoadSubmit = () => {
      upload({file:state.file,folderId:state.currentFolder.id.toString()}).then(res =>{
        if(res.data){
          ElMessage.success('上传成功！')
          getCurrentList()
          state.upLoadVisible = false
        }
      }).catch(e => console.log(e))
    }
    //初始化当前文件夹数据
    const initCurrentFolder = () => {
      state.currentFolder.tierLevel = 1
      state.currentFolder.name = "全部文件"
      state.currentFolder.parentLevel = "0"
      state.currentFolder.id = "0"
    }
    //顶部导航栏跳转
    const skip = (index) => {
      if (state.queue.length === 1){
        return; //只有全部文件按钮时不执行
      }
      for (let i = 0; i < state.queue.length - index; i++) {
        state.queue.pop()
      }
      if(index === 0){
        while (state.queue.length !== 1 && state.queue.length > 0){
          state.queue.pop()
        }
        getList("0")
        initCurrentFolder()
      }else if (state.queue.length <= 1){
        getList("0")
        initCurrentFolder()
      }else{
        var element = state.queue[state.queue.length-1]
        getList(element.id)
        state.currentFolder.tierLevel -= 1
        state.currentFolder.name = element.name
        state.currentFolder.parentLevel = element.parentLevel
        state.currentFolder.id = element.id
      }
    }
    //鼠标悬停显示
    const getHoverFolder = (element) => {
      hoverFolder(element.id).then(res =>{
        if(res.data){
          if(res.data.length === 0){
            state.hoverFolderPath = '文件夹为空'
          }else if (res.data.length > 5){
            state.hoverFolderPath = res.data.slice(0,5).join("，");
            state.hoverFolderPath += '...'
          }else{
            state.hoverFolderPath = res.data.join("，");
          }
        }
      })
    }
    //下载
    const printDoc = (val) => {
      ElMessageBox.confirm(
          '下载文件：' + val.oldFileName,
          '文件下载',
          {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning',
            center: true,
          }
      ).then(() => {
        download({fileUrl: val.fileVisitSite, oldName: val.oldFileName}).then(res =>{
          const blob = new Blob([res.data], { type: 'application/blob' })
          const reader = new FileReader()
          reader.readAsDataURL(blob)
          reader.onload = e => {
            const a = document.createElement('a')
            a.download = decodeURIComponent(val.oldFileName)
            if (typeof e.target.result === 'string') {
              a.href = e.target.result
            }
            a.click()
          }
        })
      }).catch(() => {
        ElMessage({
          type: 'info',
          message: '取消下载',
        })
      })
    }
    //文件超过数量触发
    const handleExceed = (file) => {
      uploadBanner.value.clearFiles()
      const data = file[0]
      data.uid = genFileId()
      uploadBanner.value.handleStart(data)
    }
    //多选文件
    const changCheckBox = (index) => {
      if(state.checkList[index]){
        state.map.set(state.dragList[index].id,"")
      }else{
        state.map.delete(state.dragList[index].id)
      }
    }
    //预览
    const preview = (element) => {
      state.currentSelectFile = element
      state.onlinePreviewisible = true
    }
    //打开图片预览
    const previewImage = (element) => {
      previewImageRef.value.open(element.fileVisitSite);
    }
    //打开移动文件夹
    const openMove = (element) => {
      state.currentSelectFolder = element
      state.moveVisible = true
    }
    //批量移动文件
    const batchMoveFile = () => {
      state.currentSelectFolder = null
      state.currentSelectFileIds = []
      if(state.map.size > 0){
        console.log(state.currentFolder)
        state.currentSelectFileIds.push(state.currentFolder.id) //index->0 是当前文件夹ID 后续遍历从1开始
        state.map.forEach((val,key)=>{
          state.currentSelectFileIds.push(key)
        })
        state.moveVisible = true
      }else{
        ElMessage.error("请勾选文件")
      }
    }
    onMounted(() => {
      state.map.clear()
      getList("0")
      getEnterpriseInfo().then(res =>{
        state.enterpriseInfo = res.data
        var used = state.enterpriseInfo.grossSpace - state.enterpriseInfo.surplusSpace //总-剩余
        if (used === 0){
          state.bar = 0
        }else{
          state.bar = parseInt(Math.round((used / state.enterpriseInfo.grossSpace * 100).toFixed(2))) //计算剩余空间
        }
      })
      state.queue.push({
        name:'全部文件',  //文件夹名称
        parentLevel:'0',  //父级id
        tierLevel:0,  //层级
        id:'0'
      })
    })

    return{
      ...toRefs(state),
      uploadBanner,
      previewImageRef,
      draggable,
      ElMessage,
      ElMessageBox,
      FolderMove,
      OnlinePreview,
      handleUpdateDrag,
      getList,
      newFolder,
      datadragEnd,
      searchFile,
      getFileTypeByIcon,
      convertToFileSize,
      handleMouseenter,
      handleMouseleave,
      getNextList,
      back,
      updateFolder,
      checkFolderName,
      updateFile,
      removeFolderById,
      initCurrentFolder,
      removeFileById,
      skip,
      changeFile,
      upLoadSubmit,
      getHoverFolder,
      handleMouseenterByFolder,
      printDoc,
      handleExceed,
      preview,
      previewImage,
      getCurrentList,
      openMove,
      changCheckBox,
      batchMoveFile,

    }
  },

}
</script>

<style lang="scss" scoped>
.folder {
  .list-group {
    display: flex;
    justify-content: flex-start;
    flex-wrap: wrap;
  }
  .select{
    background-color: #eaeaea;
  }

  .item:hover{
    background-color: #eaeaea;
  }

  .item{
    position: relative;
    width: 200px;
    height: 200px;
    margin: 15px;

    .constant,.constant-folder{
      width: 200px;
      height: 160px;
      font-size: 80px;
      line-height: 20px;
      text-align: center;
      .icon{
        margin-top: 40px;
      }
    }

    .constant-folder:hover{
      cursor: pointer;
    }

    .constant:hover{
      cursor: move;
    }

    .foot{
      width: 200px;
      height: 14px;
      text-overflow: ellipsis;
      text-align: center;
      .fileName{
        width: 200px;
        font-size: 12px;
        margin-bottom: 5px;
        overflow: hidden;
        text-overflow:ellipsis;
        white-space: nowrap;
      }

      .menu{
        cursor: pointer;
        position: absolute;
        right: 5px;
        top: 0;
      }

      .check{
        cursor: pointer;
        position: absolute;
        left: 15px;
        top: 0;
      }

      .none{
        display: none;
      }

      .menu .el-dropdown-link{
        font-size: 28px;
        z-index: 1000;
      }
    }
  }

  .space{
    padding-left: 10px;
    width: 10%;
    color: #84878d;
    display: inline-block;
  }

  .header{
    font-size: 14px;

    .back{
      margin-left: 10px;
      cursor: pointer;
      font-weight: 900;
      padding: 5px 5px 5px 5px;
    }

    .back:hover{
      background-color: #e7e7e7;
    }

    .path{
      margin-left: 5px;
      .icon{
        position:relative;
        top:2px;
        margin: 0 10px 0 0px;
      }
      .path-name{
        position:relative;
        top:2px;
      }
    }

    .active{
      color: #459324;
      font-weight: 700;
    }

    .pointer{
      .path-name{
        padding: 5px 5px 5px 5px;
      }
    }

    .pointer{
      .path-name:hover{
        cursor: pointer;
        background-color: #e7e7e7;
      }
    }
  }
  .icon {
    width: 1em;
    height: 1em;
    vertical-align: -0.15em;
    fill: currentColor;
    overflow: hidden;
  }
}
</style>
